
package Infoclient;

import Protocol.ReturnObject;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
 * Klasse waar de methodes voor het tekenen van de staafdiagram zich bevinden
 * @author Niels Ebbeling
 */

public class BarChartPanel extends JPanel {
    private ArrayList<Integer> valueList;
    private ArrayList<String> labelList;
    private ArrayList<Color> colorList;
    private String title;
    private String[] labels;
    private int[] values;
    
    private Infoclient ic;
    
    private int columnCounter = 0;
    
    /**
    * Constructor die ArrayLists aanmaakt.
    * @author Niels Ebbeling
    * @since 22-05-2012
    */
    
    public BarChartPanel(Infoclient ic) {
        valueList = new ArrayList();
        labelList = new ArrayList();
        colorList = new ArrayList();
        this.ic = ic;
    }
    
    /**
    * Methode die de data laat verwerken en de ArrayLists in arrays zet
    * @author Niels Ebbeling
    * @since 22-05-2012
    */    
    public void makeBarChart(String title, ReturnObject ro){
        this.title = title;
        this.processReturnObject(ro);
        values = new int[valueList.size()];
        labels = new String[labelList.size()];
        values = this.convertIntegers(valueList);
        labelList.toArray(labels);
    }
    
    /**
    * Methode die willekeurige kleuren in een arraylist zet
    * @author Roman Wiedijk
    * @since 22-05-2012
    */
    public void generateColor() {
        //Maakt 3 kleuren aan, stopt deze in een ArrayList met kleuren.
        int R = (int) (Math.random() * 256);
        int G = (int) (Math.random() * 256);
        int B = (int) (Math.random() * 256);
        colorList.add(new Color(R, G, B));
    }
    
    /**
    * Methode die het returnobject verwerkt en de gegevens in arraylists zet
    * @author Roman Wiedijk, Niels Ebbeling
    * @since 22-05-2012
    */    
    public void processReturnObject(ReturnObject ro){
        valueList.clear();
        labelList.clear();
        colorList.clear();
        
        for(String s : ro.getKolommen()){
            columnCounter++;
        }
        
        for(ArrayList a : ro.getRijen()){
            for(Object s : a){
                if(s != null){
                    if(isInt(s.toString())){
                        int currentValue = Integer.parseInt(s.toString());
                        valueList.add(currentValue);
                        generateColor();
                    } else {
                        labelList.add(s.toString());
                    }
                } else {
                    System.out.println("Nullpointer!");
                    labelList.add(" ");
                }
            }
        }
    }
    
    /**
    * Functie voor het controleren op Integers. 
    * @author Roman Wiedijk
    * @since 07-05-2012
    * @return boolean 
    */
    public boolean isInt(String string){
        try {
            //indien geen foutmelding: het is een integer.
            Integer.parseInt(string);
            return true;
        } catch (Exception e){
            //Indien foutmelding: het is geen integer.
            return false;
        }            
    }
    
    /**
    * Omzetten van arraylist naar array 
    * @since 22-05-2012
    * @author Niels Ebbeling
    * @return Array of integers
    */    
    public int[] convertIntegers(ArrayList<Integer> integers)
    {
        int[] ret = new int[integers.size()];
        for (int i=0; i < ret.length; i++)
        {
            ret[i] = integers.get(i).intValue();
        }
        return ret;
    }
    
    /**
    * Methode waar het staafdiagram wordt getekend
    * @since 22-05-2012
    * @author Niels Ebbeling, Michael Stevens
    */
    @Override
    public void paintComponent(Graphics g){
    //public void drawBarChart(Graphics g){
        super.paintComponent(g);
        if(values == null || values.length == 0) {
            return;
        }
        
        double minValue = 0;
        double maxValue = 0;
        
        for(int i = 0; i < values.length; i++) {
            if(minValue > values[i]) {
               minValue = values[i];
            }
            if(maxValue < values[i]) {
               maxValue = values[i];
            }
        }
        
        if(maxValue == minValue) {
            return;
        }
        
        Dimension d = getSize();
        int panelWidth  = d.width;
        int panelHeight = d.height - 20;
        //int barWidth = 60; //panelWidth / values.length;
        
        Font titleFont = new Font("SansSerif", Font.BOLD, 20);
        Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
        FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);
        FontMetrics labelFontMetrics = g.getFontMetrics(labelFont);
        
        int barWidth = 0;
        for(String s : labelList) {
            if(labelFontMetrics.stringWidth(s) > barWidth) {
                barWidth = labelFontMetrics.stringWidth(s);
            }
        }
        
        int titleWidth = titleFontMetrics.stringWidth(title);
        int y = titleFontMetrics.getAscent();       //Hoogte van font als Y
        int x = 5; //(panelWidth - titleWidth) / 2;      //Midden voor X (helft van het scherm min de helft van de tekst)
        
        g.setFont(titleFont);
        //g.drawString(title, x, y);
        
        int top = titleFontMetrics.getHeight();
        int bottom = labelFontMetrics.getHeight();
        
        double scale = (panelHeight - top - bottom) / (maxValue - minValue);
        
        y = panelHeight - labelFontMetrics.getDescent();
        g.setFont(labelFont);
        
        for(int i = 0; i < values.length; i++) {
            int valueX = i * barWidth + 5;
            int valueY = top;
            int height = (int) (values[i] * scale);
            if(values[i] >= 0) {
                valueY += (int) ((maxValue - values[i]) * scale);
            }else {
                valueY += (int) (maxValue * scale);
                height = -height;
            }

            //g.setColor(Color.green);
            g.setColor(colorList.get(i));
            g.fillRect(valueX, valueY, barWidth - 2, height);
            g.setColor(Color.black);
            g.drawRect(valueX, valueY, barWidth - 2, height);
            int labelWidth = labelFontMetrics.stringWidth(labels[i]);
            x = i * barWidth + (barWidth - labelWidth) / 2;            
            g.drawString(labels[i], x, y);
            g.drawString(intToString(values[i]), i * barWidth + (barWidth / 2), y - (height + 15));
            
            
        }        
            ic.getGUI().getBar().setPreferredSize(new Dimension(x + barWidth, 0));   
            ic.getGUI().getBar().revalidate();            
    }
    
    
    /**
    * Methode int omgezet wordt naar een string
    * @since 22-05-2012
    * @author Niels Ebbeling, Michael Stevens
    * @retunr String
    */
    public String intToString(int i){
        return "" + i;
    }
}